package com.dlut.txy.designpattern.schedule.executor.impl;

import com.dlut.txy.designpattern.schedule.executor.ScheduleExecutor;
import com.dlut.txy.designpattern.schedule.task.ScheduleTask;
import com.dlut.txy.designpattern.schedule.taskunit.TaskUnit;
import com.dlut.txy.designpattern.schedule.taskunit.impl.DelayQueueTaskUnit;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.DelayQueue;

@Slf4j
public class DelayQueueScheduleExecutor extends ScheduleExecutor {
    private DelayQueue<DelayQueueTaskUnit> delayQueue = new DelayQueue();
    @Override
    public ScheduleExecutor addTask(ScheduleTask scheduleTask, int scheduleMills) {
        DelayQueueTaskUnit taskUnit = new DelayQueueTaskUnit(scheduleTask, scheduleMills);
        delayQueue.add(taskUnit);
        super.taskMap.put(scheduleTask.getTaskId(), taskUnit);
        return this;
    }

    @Override
    public void runTask(String taskId) {
        // 用一个单独的线程执行延迟队列，别占用主线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    DelayQueueTaskUnit taskUnit = null;
                    try {
                        taskUnit = delayQueue.take();
                    } catch (InterruptedException e) {
                        log.info("当前任务等待中被中断，不再执行");
                        continue;
                    }
                    ScheduleTask scheduleTask = taskUnit.getScheduleTask();
                    Object result = scheduleTask.execute();
                    log.info("定时器 执行任务{} result{}", scheduleTask.getTaskId(), result);
                    // 当前元素已经取出来了，再重新加一个进去，留着下次执行
                    delayQueue.add(new DelayQueueTaskUnit(scheduleTask, taskUnit.getScheduleMills()));
                }
            }
        }).start();

    }

    @Override
    public void stopTask(String taskId) {
        if(super.taskMap.get(taskId)!=null) {
            DelayQueueTaskUnit taskUnit = (DelayQueueTaskUnit)super.taskMap.get(taskId);
            if(delayQueue.contains(taskUnit)) {
                delayQueue.remove(taskUnit);
            }
            super.taskMap.remove(taskId);
        }
    }
}
